Nous allons maintenant essayer d'appliquer les notions acquises lors des chapitres précédents à un cas d'utilisation
d'AJAX. L'exemple choisi (l'affichage du contenu d'un fichier XML) est assez simple. Cependant, il permet d'illustrer une
utilisation assez fréquente d'AJAX et d'étudier la conversion d'un document XML en document HTML au moyen d'un code javascript.
Des exemples plus complexes de programmation AJAX sont (ou seront prochainement) présentés dans la rubrique "Foire aux codes"
de notre site.
IV.2.EXERCICE: AFFICHAGE DES DONNEES D'UN FICHIER XML:
IV.2.1.INTRODUCTION:
Cette étude est présentée sous la forme d'un "travail dirigé": de ce fait, au cours de ses différentes étapes,
le lecteur est incité à effectuer différents exercices "en ligne" qui lui permettent de concrétiser et
d'expérienter les différentes notions utilisées. Il peut donc soit effectuer ces travaux et vérifier leur
résultat avant de passer à leur correction, soit aller directement à la correction.
Le mécanisme spécifique aux échanges client-serveur "AJAX" (création d'un objet XMLHttpRequest, paramétrage
et envoi de requêtes, récupération des contenus texte ou xml) a été décrit en détail au chapitre précédent.
Pour implémenter ces mécanismes dans le cas du présent exercice, nous prendrons comme ossature de programme le
code javascript présenté en exemple au précédent chapitre.
IV.2.2.OBJECTIF A ATTEINDRE:
Nous voulons afficher dans un cadre de la page web en cours de visualisation sur le navigateur du client le contenu d'un
fichier XML. Ce fichier, dont le chemin d'accès par rapport à la page en cours est
"./Dep_Chapitre_4/ListeXML_Chap4_Exemple_1.xml" et dont le contenu est donné ci-dessous, représente les affluences
mensuelles d'un site web pour une année donnée.
Rappelons qu'X.M.L (eXtensible Markup Language) permet de décrire la structure et le contenu d'un document indépendemment
de sa présentation, à l'aide de balises (markup) imbriquée formant une arborescence à partir d'une racine unique (la balise
root).
L'examen du document XML présenté ci-dessus permet d'ailleurs d'identifier de fortes similitudes entre la structure
d'un document XML et celle d'un document HTML:
La structure arborescente, décrite sous la forme de balises imbriquées (12 balises <mois> insérées dans
une balise <root>)
La déclaration et l'initialisation d'attributs dans les balises (attribut "nom" dans les balises <mois>)
La présence de contenus textuels à l'intérieur des balises ( <mois...>nombre de visites dans le mois</mois>)
Cependant, à la différence d'HTML, l'utilisateur d'X.M.L. a la possibilité de créer ses types de propres balises et les
attributs de ces balises en fonction de ses besoins (d'où le qualificatif "extensible"). Cette extensibilité (pratiquement)
illimitée permet à X.M.L. de décrire des données de nature extrêmement diverses (le contenu d'un article de journal,
d'un message, d'une base de données, etc.). Ainsi, les balises <root> et <mois> et l'attribut "nom"
apparaissant dans l'exemple sont des créations de l'utilisateur et n'ont de sens que dans le cadre du document.
D'autre part, la présentation d'un document XML ne peut être décrite que par un langage tiers (css, xsl ou xslt).
ListeXLM_Chap4_Exemple_1.xml décrit donc la structure d'une liste de 12 balises de type "mois", munies d'un attribut
"nom" dont la valeur est le nom du mois, et dont le contenu représente le nombre de visites qu'un site web a reçu durant
le mois en cours. Le problème à résoudre est d'afficher cette liste à double entrées (nom de mois --> nombre de visiteurs)
dans un cadre de la page web.
IV.2.3.ETUDE DU PROBLEME:
IV.2.3.1.RESULTAT A OBTENIR:
La différence avec l'exemple donné au chapitre III est qu'un contenu XML ne peut être directement intégré dans du code HTML:
il faut donc transformer les données reçues en un code HTML représentant la liste décrite par le document xml. Pour ne pas
augmenter trop la difficulté, on pourra se contenter de la présentation suivante:
Janvier=3201
Février=5432
Mars=4324
Avril=6127
Mai=7435
Juin=9743
Juillet=8324
Août=6753
Septembre=7654
Octobre=6428
Novembre=4567
Décembre=3895
Une partie du problème consiste donc à transformer le contenu XML reçu en un contenu HTML sémantiquement identique.
IV.2.3.2.TRANSFORMATION D'UN CONTENU XML en CONTENU HTML PAR JAVASCRIPT:
La transformation évoquée au paragraphe précédent devra être effectuée par le script javascript chargé de traiter la réponse
du serveur à la requête AJAX. Heureusement, la structure arborescente d'un contenu XML permet à javascript de le traiter comme
s'il s'agissait d'une arborescence du D.O.M. (Document Object Model):
Du fait de la structure arborescente des documents XML, de leur présentation sous la forme de balises imbriquées, de la
présence d'attributs associés aux balises et de contenus insérés dans celles-ci, le D.O.M. est tout à fait apte à
modéliser ce type de document. La conséquence est que la plupart des fonctions javascript destinées à traiter les
objets du D.O.M. sont applicables à un document XML. Par exemple, supposons qu'après une requête AJAX, le contenu
du fichier Liste_Exemple_4_1.xml se retrouve dans l'attribut responseXML de l'objet AJAX XHR:
Pour obtenir une référence sur l'objet "racine", il suffira de faire:
var racine = XHR.responseXML.documentElement;
Pour obtenir une référence sur la liste des objets "mois", il suffira de faire:
var ListeNoeuds = XHR.responseXML.getElementsByTagName("mois");
Pour obtenir la longueur de la liste des objets "mois", il suffira de faire:
var LongueurListe = ListeNoeuds.length;
Pour obtenir une référence sur l'attribut "nom" du noeud "mois" n° i, il suffira de faire:
var Attribut = ListeNoeuds[i].getAttribute("nom");
Pour obtenir une référence sur le contenu du noeud "mois" n° i, il suffira de faire:
var Contenu = ListeNoeuds[i].firstChild.nodeValue;
(car le contenu de la balise est un noeud texte qui est le premier noeud fils de cette balise).
Etc.
IV.2.3.3.CONCLUSION:
La démarche consistera donc:
A récupérer dans le logiciel client le contenu du fichier XML à traduire (grâce à une interaction AJAX).
Puis à traduire le contenu XML obtenu en une liste HTML sémantiquement identique au contenu XML reçu.
Enfin, à afficher ce contenu dans le cadre destiné à cet effet.
IV.2.4.REALISATION:
IV.2.4.1.AVANT-PROPOS:
Pour réaliser cet exemple, nous prendrons pour base le code javascript utilisé pour l'exemple du chapitre III. Nous allons
donc créer une nouvelle classe GestionAjax munie de 3 méthodes: le constructeur "GestionAjax"et les méthodes "Envoi" et
"Reception".
IV.2.4.2.REPERAGE DES MODIFICATIONS A EFFECTUER:
Le premier exercice va consister à repérer, dans le listing produit dans le cadre de l'exemple donné au chapitre III, les
lignes de code qu'il sera nécessaire de modifier ou supprimer.
0:
1: //----------------------------------------------------------------------------------------------
2: // Fichier: JS_Exemple_3_1.js
3: //----------------------------------------------------------------------------------------------
4:
5: //----------------------------------------------------------------------------------------------
6: // Constructeur de la classe GestionAjax.
7: // Le constructeur tente, en fonction du type de navigateur, de créer un objet XMLHttpRequest.
8: // Si la création est réussie, l'objet est pointé par l'attribut XHR et la fonction retourne 0
9: // Sinon, XHR contient null
10: //--------------------------------------------------------------------------------------------
11: function GestionAjax ( Envoi, Reception )
12: {
13: // DECLARATION D'ATTRIBUTS
14: this.XHR = null;
15:
16: // DECLARATION DE METHODES
17: this.Envoi = Envoi;
18: this.Reception = Reception;
19:
20: // CREATION D'UN OBJET XMLHttpRequest
21: // Tenter de créer l'objet XHR en fonction du navigateur utilisé
22: if (window.XMLHttpRequest) // Firefox
23: {
24: this.XHR = new XMLHttpRequest();
25: }
26: else if (window.ActiveXObject) // Internet Explorer
27: {
28: this.XHR = new ActiveXObject("Microsoft.XMLHTTP");
29: }
30: else
31: {
32: // Signaler que XMLHttpRequest n'est pas supporté par le navigateur
33: window.alert("Votre navigateur n'est équipé pour utiliser les objets XMLHttpRequest.");
34: }
35: }
36:
37: //--------------------------------
38: // Methode Envoi
39: //--------------------------------
40: function Envoi ()
41: {
42: // Ouverture de l'échange
43: this.XHR.open ( "get", "Dep_Chapitre_3/Contenu_Exemple_3_1.html", true); // Ouverture échange, requête GET, URL=Conten44: u.html,
45: // mode asynchrone.
46:
47: // Choisir l'encodage correspondant au traitement choisi
48: this.XHR.setRequestHeader( "Content-type", "application/x-www-form-urlencoded" );
49:
50: // Connexion l'événement de réception à la fonction de traitement
51: this.XHR.onreadystatechange = Rec; // Connexion du gestionnaire d'événement de réception à une fonction exterieure à 52:
53: // la classe. Cette fonction appellera la méthode Reception (l'appel direct de la
54: // methode ne fonctionne pas!!!)
55: // Envoi de la requète
56: this.XHR.send( "" ); // envoi de la requête avec une liste d'arguments vide
57:
58: }
59:
60: //--------------------------------
61: // Methode Reception
62: //--------------------------------
63: function Reception ()
64: {
65: // SI ( L'état de l'objet XHR est "complète") ALORS Insérer le code HTML reçu dans le cadre "Affichage"
66: if( this.XHR.readyState == 4 )
67: {
68: document.getElementById ( "Affichage" ).innerHTML = this.XHR.responseText;
69: // FINSI
70: }
71: }
72:
73: //-------------------------------------------------------------------------------------------------
74: // Cette fonction, connectée directement au gestionnaire d'événement, sert de relais pour l'appel
75: // de la méthode Reception. En effet, l'appel direct d'une méthode par un gestionnaire d'événement
76: // ne semble pas fonctionner !!!
77: //-------------------------------------------------------------------------------------------------
78: function Rec()
79: {
80: ObjGestionAjax.Reception();
81: }
82:
Saisissez dans le champ de saisie ci-dessous les numeros des lignes à modifier ou supprimer, en les séparant par des virgules
(ex: 23,45), puis activez le bouton "VERIFICATION" pour connaître le résultat de votre proposition.
Vous pouvez ensuite soit choisir de faire une autre proposition, soit activer le bouton "CORRECTION" pour connaître le corrigé.
IV.2.4.3.ELABORATION DU CONTENU HTML A PARTIR DU CONTENU XML:
ANALYSE DU TRAITEMENT ALGORITHMIQUE A EFFECTUER:
Il reste donc à écrire un code javascript répondant à la problématique posée, que l'on peut résumer ainsi:
Nous allons donc étudier l'algorithme nécessaire pour effectuer cette transformation:
Le document XML est composé d'une liste de noeuds de type "mois", comportant chacun un attribut "nom" dont la valeur est
le nom du mois correspondant au noeud. Chaque noeud contient également un texte qui représente le nombre de visites du mois.
Du point de vue du D.O.M., chaque noeud du document xml peut être associé à une balise dont le "tag" est "mois", munie de
l'attribut "nom" et possédant un noeud texte enfant représentant le nombre de visites du mois.
Il s'agit donc de traduire cette structure en une liste de type <ul> dont chaque balise <li> correspond à
chaque noeud "mois" du document XLM et possède un noeud texte fils dont le contenu est égal à un texte que l'on peut
décrire comme suit: <nom du mois> = <nombre de visites du mois>. Nous allons essayer de représenter ce traitement
par un algorithme écrit en "pseudo code":
Nous allons donc écrire un algorithme permettant d'assurer la conversion du contenu XML en contenu HTML
"./Dep_Chapitre_4/ListeXML_Chap4_Exemple_1.xml" et d'effectuer la conversion du contenu XML en HTML. Pour cela,
nous allons utiliser un outil de codage qui permettra de composer cet algorithme ligne à ligne en sélectionnant des
lignes de pseudo-code dans une liste, puis en intégrant ces lignes dans le listing.
La liste proposée contient toutes les instructions nécessaires, mais, bien sûr, celles-ci ne sont pas présentées dans le bon
ordre. D'autre part, des lignes inutiles ou erronées ont été introduites dans cette liste. A vous de sélectionner les bonnes.
Pour afficher la solution proposée dans un autre onglet, cliquez ci-contre:
Solution proposée:
,
Les différentes indications données au paragraphe IV.2.3.2 devraient permettre de traduire cet algorithme en un code
javascript répondant à la question. C'est l'exercice que nous proposons au paragraphe suivant.
ECRITURE DU PROGRAMME EN JAVASCRIPT:
Nous allons donc écrire une classe "GestionAjax" permettant d'assurer le téléchargement du fichier
"./Dep_Chapitre_4/ListeXML_Chap4_Exemple_1.xml" et d'effectuer la conversion du contenu XML en HTML. Pour cela,
nous allons de nouveau utiliser l'outil de codage. Le code javascript obtenu pourra être essayé "en ligne".
Comme précédemment, La liste proposée contient toutes les instructions nécessaires, mais, bien sûr,celles-ci ne sont pas
présentées dans le bon ordre. D'autre part, des lignes inutiles ou erronées ont été introduites dans cette liste. A vous
de sélectionner les bonnes.
Pour faciliter votre tâche, une ébauche de programme figure déja dans ce listing. Il suffira de le modifier et de le compléter
en ajoutant ou substituant des lignes sélectionnées dans le sélecteur aux lignes existantes. Lorsque vous estimerez que le
codage de la classe est terminée, vous pourrez faire une sauvegarde du listing dans un fichier, de façon à pouvoir tester son
fonctionnement (bouton "Faire une sauvegarde").
ACTIVATION DU PROGRAMME JAVASCRIPT DEPUIS LA PAGE WEB UTILISATRICE:
Il reste à intégrer dans la page web utilisatrice l'activation du code javascript. Celui-ci pourra se présenter de la façon
suivante:
...............................................
<script type="text/javascript" src="./Dep_Chapitre_4/Resultat_Chap4_Exemple_1.js"></script>
<script type="text/javascript">
var ObjGestionAjax = new GestionAjax ( Envoi, Reception ); // Création d'un objet GestionAjax
</script>
<!-- Cadre d'affichage de la liste -->
<div id="Affichage" style="width: 48%; min-height: 100px; border: 1px solid black; text-align: left;" onclick="ObjGestionAjax.Envoi();">
<-- Zone d'affichage de la liste -->
</div>
...............................................
IV.2.5.ESSAIS ET CORRECTION:
Si vous avez effectué un sauvegarde de votre listing, vous pouvez tester son fonctionnement en activant le bouton "Essayer le
code produit". Sinon, vous pouvez directement voir la correction (bouton "Etudier la solution proposée").